/*********************************************************************************
 *      Copyright:  (C) HuangXiangming
 *                  All rights reserved.
 *
 *       Filename:  socket_reconnect.c
 *    Description:  This file is connect-related function
 *                 
 *        Version:  1.0.0(25/04/03)
 *         Author:  HuangXiangming <huangxiangming@gmail.com>
 *      ChangeLog:  1, Release initial version on "25/04/03 18:18:21"
 *                 
 ********************************************************************************/
#include <netdb.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>      //socket、connect
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h> 
#include <string.h>     //strerror
#include <arpa/inet.h>

#include "socket.h"
#include "logger.h"

void print_usage(char *progname)
{
	printf("%s usage: \n", progname);
	printf("-i(--ipaddr): sepcify server IP address\n");
	printf("-p(--port): sepcify server port\n");
	printf("-h(--help): print this help information\n");
	printf("-t(--time): acquisition interval\n");
	printf("-b(--background): Enter the daemon\n");
	printf("-s(--sn): device sequence\n");
	return ;
}

//断线连接
//int socket_connect(int *sockfd, char *host, int port, int *connected)
int socket_connect(socket_t *sock)
{        
	struct sockaddr_in      	servaddr_new;     
	int                     	rv = -1; 

	log_info("1111\n");

	sock->sockfd = socket(AF_INET, SOCK_STREAM, 0);     //创建文字描述符
	if ( sock->sockfd < 0 ) 
	{    
		return -1;        //一般出错返回负数，成功返回03
	}   
					
	log_info("2222\n");

	memset(&servaddr_new, 0, sizeof(servaddr_new));
	servaddr_new.sin_family=AF_INET;
	servaddr_new.sin_port=htons(sock->port);  

	log_info("3333\n");

	if ( inet_aton(sock->hostname, &servaddr_new.sin_addr) == 0 )
	{
		log_info("Input is not a valid IPv4 address. Attempting to resolve as a domain name...\n");

		struct addrinfo 		hints, *res;		//初始化hints结构体
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_INET;
		hints.ai_socktype = SOCK_STREAM; 		// 流式套接字（TCP）
		
		//！！！解析可能包含多个ip，待修改
		int status = getaddrinfo(sock->hostname, NULL, &hints, &res);
		if (status != 0) 
		{
			log_error("Domain name resolution failed.\n");
			return -1;
		}

		struct sockaddr_in *ipv4 = (struct sockaddr_in *)res->ai_addr;
		servaddr_new.sin_addr = ipv4->sin_addr;

		freeaddrinfo(res);  // 释放资源
	}
					
	log_info("4444\n");

	rv=connect(sock->sockfd, (struct sockaddr *)&servaddr_new, sizeof(servaddr_new));
	if ( rv < 0 ) 
	{   
		close(sock->sockfd);
		return -1;
	}
	else
	{
		sock->connected = 1;
		log_info("connect to server[%s:%d] successfully!\n", sock->hostname, sock->port);
	
	}

	return 0;
}
/*
int socket_connect_cp(int *sockfd, int port,char *servip ,int *reconnect)
{        
	struct sockaddr_in      	servaddr_new;     
	int                     	rv = -1; 
		
	*sockfd=socket(AF_INET, SOCK_STREAM, 0);     //创建文字描述符
	if ( *sockfd < 0 ) 
	{    
		return -1;        //一般出错返回负数，成功返回03
	}   
	memset(&servaddr_new, 0, sizeof(servaddr_new));
	servaddr_new.sin_family=AF_INET;
	servaddr_new.sin_port=htons(port);  
	if ( inet_aton(servip, &servaddr_new.sin_addr) == 0 )
	{
		log_info("Input is not a valid IPv4 address. Attempting to resolve as a domain name...\n");
				
		struct addrinfo 		hints, *res;		//初始化hints结构体
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_INET;
		hints.ai_socktype = SOCK_STREAM; 		// 流式套接字（TCP）

		int status = getaddrinfo(servip, NULL, &hints, &res);
		if (status != 0) 
		{
			log_error("Domain name resolution failed.\n");
			return -1;
		}

		struct sockaddr_in *ipv4 = (struct sockaddr_in *)res->ai_addr;
		servaddr_new.sin_addr = ipv4->sin_addr;

		freeaddrinfo(res);  // 释放资源
	}
											                                        
	rv=connect(*sockfd, (struct sockaddr *)&servaddr_new, sizeof(servaddr_new));
	if ( rv < 0 ) 
	{   
		close(*sockfd);
		return -1;
	}
	else
	{
		*reconnect = 0;
		log_info("connect to server[%s:%d] successfully!\n", servip, port);

	}

	return 0;
}
	
*/	

int read_write(int sockfd, char *str)
{
	char 		buf[1024];
	int			rv = -1;
	int                     error;
	socklen_t               len_error = sizeof(error);

	rv=write(sockfd, str, strlen(str));
	if ( rv <= 0 )
	{
		log_warn("write to server by sockfd[%d] failure: %s\n", sockfd, strerror(errno));
		return -1;
	}

	//读取服务端信息
	memset(buf, 0, sizeof(buf));
	rv=read(sockfd, buf, sizeof(buf));
	if ( rv < 0 )
	{
		log_warn("Read data from server by sockfd[%d] failure: %s\n", sockfd, strerror(errno));
		return -1;
	}
	else if ( rv == 0 )
	{
		log_warn("Socket[%d] get disconnected\n", sockfd);
		return -1;
	}
	log_info("Read %d bytes data from Server: %s\n", rv, buf);

	return 0;

}
